/**
 * 
 */
package com.blumov.fastbox.infrastructure.persistence.dataaccess.simpledao;

import java.io.Serializable;

import org.hibernate.Criteria;
import org.hibernate.Query;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.springframework.stereotype.Repository;

import com.blumov.fastbox.domain.enums.ErrorCode;
import com.blumov.fastbox.domain.exceptions.NonBusinessException;

/**
 * a simple DAO con las operaciones basicas <br>
 * si no satisface esta implementacion <br>
 * se puede hacer otra implementacion <br>
 * y delegar a esa nueva implementacion
 */
@Repository
public final class SimpleDAOImpl implements SimpleDAO {

	private SessionFactory sessionFactory;

	public void setSessionFactory(SessionFactory sessionFactory) {
		this.sessionFactory = sessionFactory;
	}

	protected Session getSession() {
		return sessionFactory.getCurrentSession();
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see
	 * com.epidataconsulting.vonderheide.vdh.business.modelo.seguridad.SimpleDAO#create(java.lang
	 * .Object)
	 */
	public Integer save(Object obj) {
		Integer id = (Integer) getSession().save(obj);
		return id;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see
	 * com.epidataconsulting.vonderheide.vdh.business.modelo.seguridad.SimpleDAO#update(java.lang
	 * .Object)
	 */
	public void update(Object obj) {
		getSession().update(obj);
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see
	 * com.epidataconsulting.vonderheide.vdh.business.modelo.seguridad.SimpleDAO#saveOrUpdate(java
	 * .lang.Object)
	 */
	public void saveOrUpdate(Object obj) {
		getSession().saveOrUpdate(obj);
	}


	/*
	 * (non-Javadoc)
	 * 
	 * @see
	 * com.epidataconsulting.vonderheide.vdh.business.modelo.seguridad.SimpleDAO#merge(java.lang
	 * .Object)
	 */
	public Object merge(Object obj) {
		return getSession().merge(obj);
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see
	 * com.epidataconsulting.vonderheide.vdh.business.modelo.seguridad.SimpleDAO#delete(java.lang
	 * .Class, java.lang.Integer)
	 */
	@SuppressWarnings("unchecked")
	public void delete(Class theClass, Integer id) {
		Session session = getSession();
		Object obj = session.get(theClass, id);
		session.delete(obj);
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see
	 * com.epidataconsulting.vonderheide.vdh.business.modelo.seguridad.SimpleDAO#load(java.lang.
	 * Class, java.lang.Integer)
	 */
	@SuppressWarnings("unchecked")
	public Object load(Class theClass, Serializable id) {
		return getSession().load(theClass, id);
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see
	 * com.epidataconsulting.vonderheide.vdh.persistencia.dataaccess.simpledao
	 * .SimpleDAO#get(java.lang.Class, java.io.Serializable)
	 */
	@SuppressWarnings("unchecked")
	public Object get(Class theClass, Serializable id) {
		return get(theClass, id);
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see
	 * com.epidataconsulting.vonderheide.vdh.persistencia.dataaccess.simpledao.SimpleDAO#createQuery
	 * (java.lang.String)
	 */
	public Query createQuery(String queryString) {
		return getSession().createQuery(queryString);
	}
	/*
	 * (non-Javadoc)
	 * 
	 * @see
	 * com.epidataconsulting.vonderheide.vdh.persistencia.dataaccess.simpledao.SimpleDAO#createQuery
	 * (java.lang.String)
	 */
	public Query createSQLQuery(String queryString) {
		return getSession().createSQLQuery(queryString);
	}
	
	/*
	 * (non-Javadoc)
	 * 
	 * @see
	 * com.epidataconsulting.vonderheide.vdh.persistencia.dataaccess.simpledao.SimpleDAO#createCriteria
	 * (java.lang.Class)
	 */
	@SuppressWarnings("unchecked")
	public Criteria createCriteria(Class persistentClass) {
		return getSession().createCriteria(persistentClass);
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see
	 * com.epidataconsulting.vonderheide.vdh.persistencia.dataaccess.simpledao.SimpleDAO#createCriteria
	 * (java.lang.Class)
	 */
	@SuppressWarnings("unchecked")
	public Criteria createCriteria(Class persistentClass, String alias) {
		return getSession().createCriteria(persistentClass, alias);
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see
	 * com.epidataconsulting.vonderheide.vdh.persistencia.dataaccess.simpledao.SimpleDAO#getNameQuery
	 * (java.lang.String)
	 */
	public Query getNameQuery(String queryName) {
		return getSession().getNamedQuery(queryName);
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see
	 * com.epidataconsulting.vonderheide.vdh.persistencia.dataaccess.simpledao.SimpleDAO#loadOrCreate
	 * ( java.lang.Class, java.lang.Integer,
	 * com.epidataconsulting.vonderheide.vdh.business.helpers.Factory)
	 */
	@SuppressWarnings("unchecked")
	public <T> T loadOrCreate(Class clazz, Integer id, Factory<T> factory) {
		T obj = null;
		if (id == null) {
			obj = factory.create();
		} else {
			obj = (T) getSession().get(clazz, id);
			if (obj == null) {
				throw new NonBusinessException(ErrorCode.E0000);
			}
		}
		return obj;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see
	 * com.epidataconsulting.vonderheide.vdh.persistencia.dataaccess.simpledao.SimpleDAO#delete(
	 * java.lang.Object)
	 */
	public void delete(Object obj) {
		getSession().delete(obj);
	}

}
